﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using DX_DailyUtil_1._0._1.Web.App_Ctrl.logic;
using System.Reflection;
using System.Data.Linq;
using System.Dynamic;

namespace DX_DailyUtil_1._0._1.Web.App_Ctrl.util
{
    public class DB_Util_Expr : DB_Util_Base
    {

        public static MethodCallExpression createExpr(ITable aTable, Type aTableT, DB_Logic_Query aLogic)
        {
            Expression _expr_0 = null;
            ParameterExpression _para_o = Expression.Parameter(aTableT, "o");
            for (int i = 0; i < aLogic.MWhere.Count; i++)
            {
                //Expression[] _left_a = new Expression[2];
                //_left_a[0] = Expression.Constant(_para_o, typeof(ParameterExpression));
                //_left_a[1] = Expression.Constant(_tableT.GetProperty(aLogic.MWhere[i].field), typeof(PropertyInfo));
                //Expression _ll = Expression.Call(typeof(Expression), "Property", null, _left_a);

                Expression[] _expr_lr = new Expression[2];

                for (int k = 0; k < aLogic.MWhere[i].field.Length; k++)
                {
                    _expr_lr[0] = _expr_lr[0] == null ? Expression.Property(_para_o, _para_o.Type.GetProperty(aLogic.MWhere[i].field[k])) : Expression.Property(_expr_lr[0], _expr_lr[0].Type.GetProperty(aLogic.MWhere[i].field[k]));
                }

                //_expr_lr[0] = Expression.Property(_para_o, _tableT.GetProperty(aLogic.MWhere[i].field));
                Type _proType = _expr_lr[0].Type;
                _expr_lr[1] = Expression.Constant(aLogic.MWhere[i].value, _proType);


                //Expression _logic = Expression.Call(null, typeof(Expression).GetMethod(aLogic.MWhere[i].logic, BindingFlags.Static | BindingFlags.Public), _expr_lr);

                Expression _logic = (Expression)typeof(Expression).InvokeMember(aLogic.MWhere[i].logic, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, _expr_lr);

                Expression _equal = Expression.Equal(_expr_lr[0], _expr_lr[1]);

                //Expression _logic = Expression.Call(typeof(Expression), aLogic.MWhere[i].logic, null, _expr_lr);

                _expr_0 = _expr_0 == null ? _logic : Expression.AndAlso(_expr_0, _logic);
            }
            // 是不是都后带一个并且true
            Expression _default_condition = Expression.Constant(true);
            _expr_0 = _expr_0 == null ? _default_condition : Expression.AndAlso(_expr_0, _default_condition);

            LambdaExpression _pred_0 = Expression.Lambda(_expr_0, _para_o);

            MethodCallExpression _call = Expression.Call(typeof(Queryable), "Where", new Type[] { aTableT },
                Expression.Constant(aTable), _pred_0);

            //Expression.MemberInit(
            //    Expression.New(typeof(Object)),
            //new MemberBinding[] {  
            //    Expression.Bind(  
            //        Expression.Property(),  
            //        Expression.Constant( 2, typeof( int ) )  
            //    )  
            //});


            //Expression newObj = Expression.Lambda(
            //    Expression.New(
            //        typeof(object).GetConstructor(new Type[] { }), // constructor  
            //        new Expression[] { }                               // arguments  
            //    ),
            //    new ParameterExpression[] { }
            //);  



            return _call;
        }

        public static MethodCallExpression createExpr_Select(MethodCallExpression aExpr, ITable aTable, Type aTableT, DB_Logic_Query aLogic)
        {
            if (aLogic.MSelect.Count > 0)
            {
                ParameterExpression _para_o = Expression.Parameter(aTableT, "o");
                MemberBinding[] _bind = new MemberBinding[aLogic.MSelect.Count];
                for (int i = 0; i < aLogic.MSelect.Count; i++)
                {
                    Expression _para = _para_o;
                    for (int k = 0; k < aLogic.MSelect[i].field.Length; k++)
                    {
                        _para = Expression.Property(_para, _para.Type.GetProperty(aLogic.MSelect[i].field[k]));
                    }
                    _bind[i] = Expression.Bind(typeof(DB_Entity).GetProperties()[i], _para);
                }
                Expression _instenceExpr = Expression.MemberInit(Expression.New(typeof(DB_Entity).GetConstructor(new Type[] { }), new Expression[] { }), _bind);
                String sss = _instenceExpr.ToString();
                String ddd = aExpr.ToString();

                LambdaExpression _pred_0 = Expression.Lambda(_instenceExpr, _para_o);
                MethodInfo[] kdkd = aExpr.Type.GetMethods();

                MethodCallExpression _tran = Expression.Call(aExpr.Type, "AsQueryable", null, null);

                MethodCallExpression _call = Expression.Call(_tran.Type, "Select", new Type[] { aTableT, typeof(DB_Entity) },
                Expression.Constant(aTable), _pred_0);

                return _call;
            }
            else
            {
                return aExpr;
            }

        }

        public class DB_Entity
        {
            private Object self;

            public Object Self
            {
                get { return self; }
                set { self = value; }
            }
            private Object fk_Objt;

            public Object Fk_Objt
            {
                get { return fk_Objt; }
                set { fk_Objt = value; }
            }
        }


    }
}